home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
role
/
Ang261Lib.lha
/
src
/
misc2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-22
|
93KB
|
3,676 lines
/*
* misc2.c: misc code for maintaining the dungeon, printing player info
*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
* This software may be copied and distributed for educational, research, and
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
#include "monster.h"
/* include before constant.h because param.h defines NULL incorrectly */
#ifndef USG
#include <sys/types.h>
#include <sys/param.h>
#endif
#include "constant.h"
#include "config.h"
#include "types.h"
#include "externs.h"
#include <ctype.h>
#ifdef USG
#ifndef ATARIST_MWC
#include <string.h>
#else
char *index();
#endif
#else
#include <strings.h>
#endif
/* Lets do all prototypes correctly.... -CWS */
#ifndef NO_LINT_ARGS
#ifdef __STDC__
static void prt_lnum(const char *, int32, int, int);
static void prt_num(const char *, int, int, int);
static void prt_long(int32, int, int);
static void prt_int(int, int, int);
#else
static void prt_lnum();
static void prt_num();
static void prt_long();
static void prt_int();
#endif
static void gain_level();
#endif
static const char *stat_names[] = { "STR: ", "INT: ", "WIS: ",
"DEX: ", "CON: ", "CHR: "};
#define BLANK_LENGTH 24
static char blank_string[] = " ";
extern int rating;
/* Places a particular trap at location y, x -RAK- */
void
place_trap(y, x, subval)
int y, x, subval;
{
register int cur_pos;
if (!in_bounds(y, x))
return; /* abort! -CFT */
if (cave[y][x].cptr >= MIN_MONIX)
return; /* don't put rubble under monsters, it's annoying -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return; /* don't replace stairs, stores, artifacts */
else
delete_object(y, x);
cur_pos = popt();
cave[y][x].tptr = cur_pos;
invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval);
}
/* Places rubble at location y, x -RAK- */
void
place_rubble(y, x)
int y, x;
{
register int cur_pos;
register cave_type *cave_ptr;
if (!in_bounds(y, x))
return; /* abort! -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return; /* don't replace stairs, stores, artifacts */
else
delete_object(y, x);
cur_pos = popt();
cave_ptr = &cave[y][x];
cave_ptr->tptr = cur_pos;
cave_ptr->fval = BLOCKED_FLOOR;
invcopy(&t_list[cur_pos], OBJ_RUBBLE);
}
/* if killed a 'Creeping _xxx_ coins'... -CWS */
void
get_coin_type(c_ptr)
creature_type *c_ptr;
{
if (!stricmp(c_ptr->name, "Creeping copper coins")) {
coin_type = 2;
}
if (!stricmp(c_ptr->name, "Creeping silver coins")) {
coin_type = 5;
}
if (!stricmp(c_ptr->name, "Creeping gold coins")) {
coin_type = 10;
}
if (!stricmp(c_ptr->name, "Creeping mithril coins")) {
coin_type = 16;
}
if (!stricmp(c_ptr->name, "Creeping adamantite coins")) {
coin_type = 17;
}
}
/* Places a treasure (Gold or Gems) at given row, column -RAK- */
void
place_gold(y, x)
int y, x;
{
register int i, cur_pos;
register inven_type *t_ptr;
if (!in_bounds(y, x))
return; /* abort! -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return; /* don't replace stairs, stores, artifacts */
else
delete_object(y, x);
cur_pos = popt();
i = ((randint(object_level + 2) + 2) / 2) - 1;
if (randint(OBJ_GREAT) == 1)
i += randint(object_level + 1);
if (i >= MAX_GOLD)
i = MAX_GOLD - 1;
if (coin_type) { /* if killed a Creeping _xxx_ coins... */
if (coin_type > MAX_GOLD - 1)
coin_type = 0; /* safety check -CWS */
i = coin_type;
}
cave[y][x].tptr = cur_pos;
invcopy(&t_list[cur_pos], OBJ_GOLD_LIST + i);
t_ptr = &t_list[cur_pos];
t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8);
/* average the values to make Creeping _xxx_ coins not give too great treasure drops */
if (coin_type)
t_ptr->cost = ((8L * (long)randint((int)object_list[OBJ_GOLD_LIST + i].cost))
+ (t_ptr->cost)) >> 1;
if (cave[y][x].cptr == 1)
msg_print("You feel something roll beneath your feet.");
}
/* Returns the array number of a random object -RAK- */
int
get_obj_num(level, good)
int level, good;
{
register int i, j;
do {
if (level == 0)
i = randint(t_level[0]) - 1;
else {
if (level >= MAX_OBJ_LEVEL)
level = MAX_OBJ_LEVEL;
else if (randint(OBJ_GREAT) == 1) {
level = level * MAX_OBJ_LEVEL / randint(MAX_OBJ_LEVEL) + 1;
if (level > MAX_OBJ_LEVEL)
level = MAX_OBJ_LEVEL;
}
/*
* This code has been added to make it slightly more likely to get
* the higher level objects. Originally a uniform distribution
* over all objects less than or equal to the dungeon level. This
* distribution makes a level n objects occur approx 2/n% of the time
* on level n, and 1/2n are 0th level.
*/
if (randint(2) == 1)
i = randint(t_level[level]) - 1;
else { /* Choose three objects, pick the highest level. */
i = randint(t_level[level]) - 1;
j = randint(t_level[level]) - 1;
if (i < j)
i = j;
j = randint(t_level[level]) - 1;
if (i < j)
i = j;
j = object_list[sorted_objects[i]].level;
if (j == 0)
i = randint(t_level[0]) - 1;
else
i = randint(t_level[j] - t_level[j - 1]) - 1 + t_level[j - 1];
}
}
} while (((object_list[sorted_objects[i]].rare ?
(randint(object_list[sorted_objects[i]].rare) - 1) : 0) && !good)
|| (object_list[sorted_objects[i]].rare == 255));
return (i);
}
int
special_place_object(y, x)
int y, x;
{
register int cur_pos, tmp;
char str[100];
int done = 0;
if (!in_bounds(y, x))
return 0; /* abort! -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return 0; /* don't replace stairs, stores, artifacts */
else
delete_object(y, x);
str[0] = 0;
again:
if (done > 20)
return 0;
tmp = randint(MAX_OBJECTS - (SPECIAL_OBJ - 1)) + (SPECIAL_OBJ - 1) - 1;
switch (tmp) {
case (SPECIAL_OBJ - 1):
done++;
if (randint(30) > 1)
goto again;
if (NARYA)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(50) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Narya");
else
good_item_flag = TRUE;
NARYA = TRUE;
break;
case (SPECIAL_OBJ):
done++;
if (randint(35) > 1)
goto again;
if (NENYA)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(60) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Nenya");
else
good_item_flag = TRUE;
NENYA = TRUE;
break;
case (SPECIAL_OBJ + 1):
done++;
if (randint(40) > 1)
goto again;
if (VILYA)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(70) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Vilya");
else
good_item_flag = TRUE;
VILYA = TRUE;
break;
case (SPECIAL_OBJ + 2):
done++;
if (randint(60) > 1)
goto again;
if (POWER)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(100) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Power (The One Ring)");
else
good_item_flag = TRUE;
POWER = TRUE;
break;
case (SPECIAL_OBJ + 3):
done++;
if (PHIAL)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(30) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Phial of Galadriel");
else
good_item_flag = TRUE;
PHIAL = TRUE;
break;
case (SPECIAL_OBJ + 4):
done++;
if (randint(10) > 1)
goto again;
if (INGWE)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(50) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Amulet of Ingwe");
else
good_item_flag = TRUE;
INGWE = TRUE;
break;
case (SPECIAL_OBJ + 5):
done++;
if (randint(6) > 1)
goto again;
if (CARLAMMAS)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(35) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Amulet of Carlammas");
else
good_item_flag = TRUE;
CARLAMMAS = TRUE;
break;
case (SPECIAL_OBJ + 6):
done++;
if (randint(8) > 1)
goto again;
if (ELENDIL)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(30) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Star of Elendil");
else
good_item_flag = TRUE;
ELENDIL = TRUE;
break;
case (SPECIAL_OBJ + 7):
done++;
if (randint(18) > 1)
goto again;
if (THRAIN)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(60) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Arkenstone of Thrain");
else
good_item_flag = TRUE;
THRAIN = TRUE;
break;
case (SPECIAL_OBJ + 8):
done++;
if (randint(25) > 1)
goto again;
if (TULKAS)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(65) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Ring of Tulkas");
else
good_item_flag = TRUE;
TULKAS = TRUE;
break;
case (SPECIAL_OBJ + 9):
done++;
if (randint(25) > 1)
goto again;
if (NECKLACE)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(60) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Necklace of the Dwarves");
else
good_item_flag = TRUE;
NECKLACE = TRUE;
break;
case (SPECIAL_OBJ + 10):
done++;
if (randint(20) > 1)
goto again;
if (BARAHIR)
goto again;
if ((object_list[tmp].level - 40) > object_level)
goto again;
if ((object_list[tmp].level > object_level) && (randint(50) > 1))
goto again;
if ((wizard || peek))
sprintf(str, "Ring of Barahir");
else
good_item_flag = TRUE;
BARAHIR = TRUE;
break;
}
if (strlen(str) > 0 && (wizard || peek))
msg_print(str);
cur_pos = popt();
cave[y][x].tptr = cur_pos;
invcopy(&t_list[cur_pos], tmp);
t_list[cur_pos].timeout = 0;
t_list[cur_pos].ident |= ID_NOSHOW_TYPE; /* don't show (+x of yyy) for these */
if (object_list[tmp].level > object_level) {
rating += 2 * (object_list[sorted_objects[tmp]].level - object_level);
}
if (cave[y][x].cptr == 1)
msg_print("You feel something roll beneath your feet.");
return (-1);
}
/* Places an object at given row, column co-ordinate -RAK- */
void
place_object(y, x)
int y, x;
{
register int cur_pos, tmp;
if (!in_bounds(y,x)) return; /* abort! -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return; /* don't replace stairs, stores, artifacts */
else
delete_object(y,x);
if (randint(MAX_OBJECTS)>SPECIAL_OBJ && randint(10)==1)
if (special_place_object(y,x)==(-1))
return;
cur_pos = popt();
cave[y][x].tptr = cur_pos;
do { /* don't generate another chest if opening_chest is true -CWS */
tmp = get_obj_num(dun_level, FALSE);
} while (opening_chest && (object_list[sorted_objects[tmp]].tval == TV_CHEST));
invcopy(&t_list[cur_pos], sorted_objects[tmp]);
magic_treasure(cur_pos, dun_level, FALSE, 0);
if (object_list[sorted_objects[tmp]].level > dun_level)
rating += object_list[sorted_objects[tmp]].level - dun_level;
if (peek) {
if (object_list[sorted_objects[tmp]].level > dun_level) {
char buf[200];
int8u temp;
temp=t_list[cur_pos].ident;
t_list[cur_pos].ident |= ID_STOREBOUGHT;
objdes(buf, &t_list[cur_pos], TRUE);
t_list[cur_pos].ident = temp;
msg_print(buf);
}
}
if (cave[y][x].cptr == 1)
msg_print ("You feel something roll beneath your feet.");
}
/* Places a GOOD-object at given row, column co-ordinate ~Ludwig */
void
place_special(y, x, good)
int y, x;
int32u good;
{
register int cur_pos, tmp;
int tv, is_good = FALSE;
if (!in_bounds(y, x))
return; /* abort! -CFT */
if (cave[y][x].tptr != 0)
if ((t_list[cave[y][x].tptr].tval == TV_STORE_DOOR) ||
(t_list[cave[y][x].tptr].tval == TV_UP_STAIR) ||
(t_list[cave[y][x].tptr].tval == TV_DOWN_STAIR) ||
((t_list[cave[y][x].tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave[y][x].tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave[y][x].tptr].flags2 & TR_ARTIFACT)))
return; /* don't replace stairs, stores, artifacts */
else
delete_object(y, x);
if (randint(10) == 1)
if (special_place_object(y, x) == (-1))
return;
cur_pos = popt();
cave[y][x].tptr = cur_pos;
do {
tmp = get_obj_num((object_level + 10), TRUE);
tv = object_list[sorted_objects[tmp]].tval;
if ((tv == TV_HELM) || (tv == TV_SHIELD) ||
(tv == TV_CLOAK) || (tv == TV_HAFTED) || (tv == TV_POLEARM) ||
(tv == TV_BOW) || (tv == TV_BOLT) || (tv == TV_ARROW) ||
(tv == TV_BOOTS) || (tv == TV_GLOVES))
is_good = TRUE;
if ((tv == TV_SWORD) &&
strncmp("& Broken", object_list[sorted_objects[tmp]].name, 8))
is_good = TRUE; /* broken swords/daggers are NOT good!
* -CFT */
if ((tv == TV_HARD_ARMOR) &&
strncmp("Rusty", object_list[sorted_objects[tmp]].name, 5))
is_good = TRUE; /* rusty chainmail is NOT good! -CFT */
if ((tv == TV_SOFT_ARMOR) &&
stricmp("some filthy rags", object_list[sorted_objects[tmp]].name))
is_good = TRUE; /* nor are rags! -CFT */
if ((tv == TV_MAGIC_BOOK) && /* if book, good must be one of the
* deeper, special must be Raal's */
(object_list[sorted_objects[tmp]].subval > ((good & SPECIAL) ? 71 : 67)))
is_good = TRUE;
if ((tv == TV_PRAYER_BOOK) && /* if book, good must be one of the
* deeper, special must be Wrath of
* God */
(object_list[sorted_objects[tmp]].subval > ((good & SPECIAL) ? 71 : 67)))
is_good = TRUE;
} while (!is_good);
invcopy(&t_list[cur_pos], sorted_objects[tmp]);
magic_treasure(cur_pos, object_level, (good & SPECIAL) ? 666 : 1, 0);
if (peek) {
if (object_list[sorted_objects[tmp]].level > object_level) {
char buf[200];
int8u t;
t = t_list[cur_pos].ident;
t_list[cur_pos].ident |= ID_STOREBOUGHT;
objdes(buf, &t_list[cur_pos], TRUE);
t_list[cur_pos].ident = t;
msg_print(buf);
}
}
if (cave[y][x].cptr == 1)
msg_print("You feel something roll beneath your feet.");
}
/* Allocates an object for tunnels and rooms -RAK- */
void
alloc_object(alloc_set, typ, num)
int (*alloc_set) ();
int typ, num;
{
register int i, j, k;
for (k = 0; k < num; k++) {
do {
i = randint(cur_height) - 1;
j = randint(cur_width) - 1;
}
/*
* don't put an object beneath the player, this could cause problems if
* player is standing under rubble, or on a trap
*/
while ((!(*alloc_set) (cave[i][j].fval)) ||
(cave[i][j].tptr != 0) || (i == char_row && j == char_col));
if (typ < 4) { /* typ == 2 not used, used to be visible
* traps */
if (typ == 1)
place_trap(i, j, randint(MAX_TRAP) - 1); /* typ == 1 */
else
place_rubble(i, j);/* typ == 3 */
} else {
object_level = dun_level;
if (typ == 4)
place_gold(i, j); /* typ == 4 */
else
place_object(i, j);/* typ == 5 */
}
}
}
/* Creates objects nearby the coordinates given -RAK- */
void
random_object(y, x, num)
int y, x, num;
{
register int i, j, k;
register cave_type *cave_ptr;
do {
i = 0;
do {
do {
j = y - 3 + randint(5);
k = x - 4 + randint(7);
} while (!in_bounds(j, k));
cave_ptr = &cave[j][k];
if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0)) {
object_level = dun_level;
if (randint(100) < 75)
place_object(j, k);
else
place_gold(j, k);
i = 9;
}
i++;
}
while (i <= 10);
num--;
}
while (num != 0);
}
void
special_random_object(y, x, num)
int y, x, num;
{
register int i, j, k;
register cave_type *cave_ptr;
object_level = dun_level;
do {
i = 0;
do {
j = y - 3 + randint(5);
k = x - 4 + randint(7);
cave_ptr = &cave[j][k];
if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0)) {
if (randint(5) == 1) {
if (!special_place_object(j, k))
place_special(j, k, SPECIAL);
} else {
place_special(j, k, SPECIAL);
}
i = 9;
}
i++;
}
while (i <= 10);
num--;
}
while (num != 0);
}
/* Converts stat num into string -RAK- */
void
cnv_stat(my_stat, out_val)
int my_stat;
char *out_val;
{
register int16u stat = my_stat;
register int part1, part2;
if (stat > 18) {
part1 = 18;
part2 = stat - 18;
if (part2 >= 220)
(void)sprintf(out_val, "%2d/*** ", part1);
else if (part2 >= 100)
(void)sprintf(out_val, "%2d/%03d ", part1, part2);
else
(void)sprintf(out_val, " %2d/%02d ", part1, part2);
} else
(void)sprintf(out_val, "%6d ", stat);
}
/* Print character stat in given row, column -RAK- */
void
prt_stat(stat)
int stat;
{
vtype out_val1;
cnv_stat(py.stats.use_stat[stat], out_val1);
put_buffer(stat_names[stat], 5 + stat, STAT_COLUMN);
put_buffer(out_val1, 5 + stat, STAT_COLUMN + 6);
}
/* Print character info in given row, column -RAK- */
/* the longest title is 13 characters, so only pad to 13 */
void
prt_field(info, row, column)
const char *info;
int row, column;
{
put_buffer(&blank_string[BLANK_LENGTH - 13], row, column);
put_buffer(info, row, column);
}
/* Print long number with header at given row, column */
static void
prt_lnum(header, num, row, column)
const char *header;
int32 num;
int row, column;
{
vtype out_val;
(void)sprintf(out_val, "%s%9ld", header, (long)num);
put_buffer(out_val, row, column);
}
/* Print number with header at given row, column -RAK- */
static void
prt_num(header, num, row, column)
const char *header;
int num, row, column;
{
vtype out_val;
(void)sprintf(out_val, "%s %6d", header, num);
put_buffer(out_val, row, column);
}
/* Print long number at given row, column */
static void
prt_long(num, row, column)
int32 num;
int row, column;
{
vtype out_val;
(void)sprintf(out_val, "%9ld", (long)num);
put_buffer(out_val, row, column);
}
/* Print number at given row, column -RAK- */
static void
prt_int(num, row, column)
int num, row, column;
{
vtype out_val;
(void)sprintf(out_val, "%6d", num);
put_buffer(out_val, row, column);
}
/* Adjustment for wisdom/intelligence -JWT- */
int
stat_adj(stat)
int stat;
{
register int value;
value = py.stats.use_stat[stat];
if (value > 228)
return (20);
else if (value > 218)
return (18);
else if (value > 198)
return (16);
else if (value > 188)
return (15);
else if (value > 178)
return (14);
else if (value > 168)
return (13);
else if (value > 158)
return (12);
else if (value > 148)
return (11);
else if (value > 138)
return (10);
else if (value > 128)
return (9);
else if (value > 118)
return (8);
else if (value == 118)
return (7);
else if (value > 107)
return (6);
else if (value > 87)
return (5);
else if (value > 67)
return (4);
else if (value > 17)
return (3);
else if (value > 14)
return (2);
else if (value > 7)
return (1);
else
return (0);
}
/* Adjustment for charisma -RAK- */
/* Percent decrease or increase in price of goods */
int
chr_adj()
{
register int charisma;
charisma = py.stats.use_stat[A_CHR];
if (charisma > 217)
return (80);
else if (charisma > 187)
return (86);
else if (charisma > 147)
return (88);
else if (charisma > 117)
return (90);
else if (charisma > 107)
return (92);
else if (charisma > 87)
return (94);
else if (charisma > 67)
return (96);
else if (charisma > 18)
return (98);
else
switch (charisma) {
case 18:
return (100);
case 17:
return (101);
case 16:
return (102);
case 15:
return (103);
case 14:
return (104);
case 13:
return (106);
case 12:
return (108);
case 11:
return (110);
case 10:
return (112);
case 9:
return (114);
case 8:
return (116);
case 7:
return (118);
case 6:
return (120);
case 5:
return (122);
case 4:
return (125);
case 3:
return (130);
default:
return (140);
}
}
/* Returns a character's adjustment to hit points -JWT- */
int
con_adj()
{
register int con;
con = py.stats.use_stat[A_CON];
if (con < 7)
return (con - 7);
else if (con < 17)
return (0);
else if (con == 17)
return (1);
else if (con < 94)
return (2);
else if (con < 117)
return (3);
else if (con < 119)
return (4);
else if (con < 128)
return (5);
else if (con < 138)
return (6);
else if (con < 158)
return (7);
else if (con < 168)
return (8);
else if (con < 178)
return (9);
else if (con < 188)
return (10);
else if (con < 198)
return (11);
else if (con < 208)
return (12);
else if (con < 228)
return (13);
else
return (14);
}
const char *
title_string()
{
const char *p;
if (py.misc.lev < 1)
p = "Babe in arms";
else if (py.misc.lev <= MAX_PLAYER_LEVEL)
p = player_title[py.misc.pclass][py.misc.lev - 1];
else if (py.misc.male)
p = "**KING**";
else
p = "**QUEEN**";
return p;
}
/* Prints title of character -RAK- */
void
prt_title()
{
prt_field(title_string(), 3, STAT_COLUMN);
}
/* Prints level -RAK- */
void
prt_level()
{
prt_int((int)py.misc.lev, 12, STAT_COLUMN + 6);
}
/* Prints players current mana points. -RAK- */
void
prt_cmana()
{
prt_int(py.misc.cmana, 14, STAT_COLUMN + 6);
}
/* Prints Max hit points -RAK- */
void
prt_mhp()
{
prt_int(py.misc.mhp, 15, STAT_COLUMN + 6);
}
/* Prints players current hit points -RAK- */
void
prt_chp()
{
prt_int(py.misc.chp, 16, STAT_COLUMN + 6);
}
/* prints current AC -RAK- */
void
prt_pac()
{
prt_int(py.misc.dis_ac, 18, STAT_COLUMN + 6);
}
/* Prints current gold -RAK- */
void
prt_gold()
{
prt_long(py.misc.au, 19, STAT_COLUMN + 3);
}
/* Prints depth in stat area -RAK- */
void
prt_depth()
{
vtype depths;
register int depth;
depth = dun_level * 50;
if (depth == 0)
(void)strcpy(depths, "Town ");
else
(void)sprintf(depths, "%d ft", depth);
prt(depths, 23, 70);
}
/* Prints status of hunger -RAK- */
void
prt_hunger()
{
if (PY_WEAK & py.flags.status)
put_buffer("Weak ", 23, 0);
else if (PY_HUNGRY & py.flags.status)
put_buffer("Hungry", 23, 0);
else
put_buffer(" ", 23, 0);
}
/* Prints Blind status -RAK- */
void
prt_blind()
{
if (PY_BLIND & py.flags.status)
put_buffer("Blind", 23, 7);
else
put_buffer(" ", 23, 7);
}
/* Prints Confusion status -RAK- */
void
prt_confused()
{
if (PY_CONFUSED & py.flags.status)
put_buffer("Confused", 23, 13);
else
put_buffer(" ", 23, 13);
}
/* Prints Fear status -RAK- */
void
prt_afraid()
{
if (PY_FEAR & py.flags.status)
put_buffer("Afraid", 23, 22);
else
put_buffer(" ", 23, 22);
}
/* Prints Poisoned status -RAK- */
void
prt_poisoned()
{
if (PY_POISONED & py.flags.status)
put_buffer("Poisoned", 23, 29);
else
put_buffer(" ", 23, 29);
}
/* Prints Searching, Resting, Paralysis, or 'count' status -RAK- */
void
prt_state()
{
char tmp[16];
py.flags.status &= ~PY_REPEAT;
if (py.flags.paralysis > 1)
put_buffer("Paralysed ", 23, 38);
else if (PY_REST & py.flags.status) {
if (py.flags.rest > 0)
(void)sprintf(tmp, "Rest %-5d", py.flags.rest);
else if (py.flags.rest == -1)
(void)sprintf(tmp, "Rest *****");
else if (py.flags.rest == -2)
(void)sprintf(tmp, "Rest &&&&&");
put_buffer(tmp, 23, 38);
} else if (command_count > 0) {
(void)sprintf(tmp, "Repeat %-3d", command_count);
py.flags.status |= PY_REPEAT;
put_buffer(tmp, 23, 38);
if (PY_SEARCH & py.flags.status)
put_buffer("Search ", 23, 38);
} else if (PY_SEARCH & py.flags.status)
put_buffer("Searching ", 23, 38);
else /* "repeat 999" is 10 characters */
put_buffer(" ", 23, 38);
}
/* Prints the speed of a character. -CJS- */
void
prt_speed()
{
register int i;
i = py.flags.speed;
if (PY_SEARCH & py.flags.status) /* Search mode. */
i--;
if (i > 2)
put_buffer("Extremely Slow", 23, 49);
else if (i == 2)
put_buffer("Very Slow ", 23, 49);
else if (i == 1)
put_buffer("Slow ", 23, 49);
else if (i == 0)
put_buffer(" ", 23, 49);
else if (i == -1)
put_buffer("Fast ", 23, 49);
else if (i == -2)
put_buffer("Very Fast ", 23, 49);
else if (i == -3)
put_buffer("Extremely Fast", 23, 49);
else if (i == -4)
put_buffer("Deadly Speed ", 23, 49);
else
put_buffer("Light Speed ", 23, 49);
}
void
prt_study()
{
py.flags.status &= ~PY_STUDY;
if (py.flags.new_spells != 0)
put_buffer("Study", 23, 64);
else
put_buffer(" ", 23, 64);
}
void
cut_player(c)
int c;
{
py.flags.cut += c;
c = py.flags.cut;
if (c > 5000)
msg_print("You have been given a mortal wound.");
else if (c > 900)
msg_print("You have been given a deep gash.");
else if (c > 200)
msg_print("You have been given a severe cut.");
else if (c > 100)
msg_print("You have been given a nasty cut.");
else if (c > 50)
msg_print("You have been given a bad cut.");
else if (c > 10)
msg_print("You have been given a light cut.");
else if (c > 0)
msg_print("You have been given a graze.");
}
void
prt_cut()
{
int c = py.flags.cut;
if (c > 900)
put_buffer("Mortal wound", 21, 0);
else if (c > 300)
put_buffer("Deep gash ", 21, 0);
else if (c > 200)
put_buffer("Severe cut ", 21, 0);
else if (c > 45)
put_buffer("Nasty cut ", 21, 0);
else if (c > 15)
put_buffer("Bad cut ", 21, 0);
else if (c > 5)
put_buffer("Light cut ", 21, 0);
else if (c > 0)
put_buffer("Graze ", 21, 0);
else
put_buffer(" ", 21, 0);
}
void
stun_player(s)
int s;
{
int t;
if (!py.flags.sound_resist) {
t = py.flags.stun;
py.flags.stun += s;
s = py.flags.stun;
if (s > 100) {
msg_print("You have been knocked out.");
if (t == 0) {
py.misc.ptohit -= 20;
py.misc.ptodam -= 20;
py.misc.dis_th -= 20;
py.misc.dis_td -= 20;
} else if (t <= 50) {
py.misc.ptohit -= 15;
py.misc.ptodam -= 15;
py.misc.dis_th -= 15;
py.misc.dis_td -= 15;
}
} else if (s > 50) {
msg_print("You've been heavily stunned.");
if (t == 0) {
py.misc.ptohit -= 20;
py.misc.ptodam -= 20;
py.misc.dis_th -=20;
py.misc.dis_td -=20;
} else if (t <= 50) {
py.misc.ptohit -= 15;
py.misc.ptodam -= 15;
py.misc.dis_th -= 15;
py.misc.dis_td -= 15;
}
} else if (s > 0) {
msg_print("You've been stunned.");
if (t == 0) {
py.misc.ptohit -= 5;
py.misc.ptodam -= 5;
py.misc.dis_th -= 5;
py.misc.dis_td -= 5;
}
}
}
}
void
prt_stun()
{
int s = py.flags.stun;
if (!py.flags.sound_resist) {
if (s > 100)
put_buffer("Knocked out ", 22, 0);
else if (s > 50)
put_buffer("Heavy stun ", 22, 0);
else if (s > 0)
put_buffer("Stun ", 22, 0);
else
put_buffer(" ", 22, 0);
}
}
/* Prints winner status on display -RAK- */
void
prt_winner()
{
if (wizard)
put_buffer("Wizard", 20, 0);
else if (total_winner)
put_buffer("Winner", 20, 0);
else
put_buffer(" ", 20, 0);
}
int16u
modify_stat(stat, amount)
int stat;
int amount;
{
register int loop, i;
register int16u tmp_stat;
tmp_stat = py.stats.cur_stat[stat];
loop = (amount < 0 ? -amount : amount);
for (i = 0; i < loop; i++) {
if (amount > 0) {
if (tmp_stat < 18)
tmp_stat++;
else
tmp_stat += 10;
} else {
if (tmp_stat > 27)
tmp_stat -= 10;
else if (tmp_stat > 18)
tmp_stat = 18;
else if (tmp_stat > 3)
tmp_stat--;
}
}
return tmp_stat;
}
/* Set the value of the stat which is actually used. -CJS- */
void
set_use_stat(stat)
int stat;
{
py.stats.use_stat[stat] = modify_stat(stat, py.stats.mod_stat[stat]);
if (stat == A_STR) {
py.flags.status |= PY_STR_WGT;
calc_bonuses();
} else if (stat == A_DEX)
calc_bonuses();
else if (stat == A_INT && class[py.misc.pclass].spell == MAGE) {
calc_spells(A_INT);
calc_mana(A_INT);
} else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST) {
calc_spells(A_WIS);
calc_mana(A_WIS);
} else if (stat == A_CON)
calc_hitpoints();
}
/* Increases a stat by one randomized level -RAK- */
int
inc_stat(stat)
register int stat;
{
register int tmp_stat, gain;
res_stat(stat);
tmp_stat = py.stats.cur_stat[stat];
if (tmp_stat < 118) {
if (tmp_stat < 18) {
gain = randint(2); /* let's be able to monitor the increase -CWS */
tmp_stat += gain;
} else if (tmp_stat < 116) {
/* stat increases by 1/6 to 1/3 of difference from max */
gain = ((118 - tmp_stat) / 2 + 3) >> 1;
tmp_stat += randint(gain) + gain / 2;
if (tmp_stat > 117)
tmp_stat = 117;
} else
tmp_stat++;
py.stats.cur_stat[stat] = tmp_stat;
if (tmp_stat > py.stats.max_stat[stat])
py.stats.max_stat[stat] = tmp_stat;
set_use_stat(stat);
prt_stat(stat);
return TRUE;
} else
return FALSE;
}
/* Decreases a stat by one randomized level -RAK- */
int
dec_stat(stat)
register int stat;
{
register int tmp_stat, loss;
tmp_stat = py.stats.cur_stat[stat];
if (tmp_stat > 3) {
if (tmp_stat < 19)
tmp_stat--;
else if (tmp_stat < 117) {
loss = (((118 - tmp_stat) >> 1) + 1) >> 1;
tmp_stat += -randint(loss) - loss;
if (tmp_stat < 18)
tmp_stat = 18;
} else
tmp_stat--;
py.stats.cur_stat[stat] = tmp_stat;
set_use_stat(stat);
prt_stat(stat);
return TRUE;
} else
return FALSE;
}
/* Restore a stat. Return TRUE only if this actually makes a difference. */
int
res_stat(stat)
int stat;
{
register int i;
i = py.stats.max_stat[stat] - py.stats.cur_stat[stat];
if (i) {
py.stats.cur_stat[stat] += i;
set_use_stat(stat);
prt_stat(stat);
return TRUE;
}
return FALSE;
}
/*
* Boost a stat artificially (by wearing something). If the display argument
* is TRUE, then increase is shown on the screen.
*/
void
bst_stat(stat, amount)
int stat, amount;
{
py.stats.mod_stat[stat] += amount;
set_use_stat(stat);
/* can not call prt_stat() here, may be in store, may be in inven_command */
py.flags.status |= (PY_STR << stat);
}
/* Returns a character's adjustment to hit. -JWT- */
int
tohit_adj()
{
register int total, stat;
stat = py.stats.use_stat[A_DEX];
if (stat < 4) total = -3;
else if (stat < 6) total = -2;
else if (stat < 8) total = -1;
else if (stat < 16) total = 0;
else if (stat < 17) total = 1;
else if (stat < 18) total = 2;
else if (stat < 69) total = 3;
else if (stat < 108) total = 4; /* 18/51 to 18/89 -CFT */
else if (stat < 118) total = 5; /* 18/90 to 18/99 -CFT */
else if (stat < 128) total = 6; /* 18/100 to 18/109 -CFT */
else if (stat < 138) total = 7;
else if (stat < 148) total = 8;
else if (stat < 158) total = 9;
else if (stat < 168) total = 10;
else if (stat < 178) total = 11;
else if (stat < 188) total = 12;
else if (stat < 198) total = 13;
else if (stat < 218) total = 14;
else if (stat < 228) total = 15;
else total = 17;
stat = py.stats.use_stat[A_STR];
if (stat < 4) total -= 3;
else if (stat < 5) total -= 2;
else if (stat < 7) total -= 1;
else if (stat < 18) total -= 0;
else if (stat < 88) total += 1; /* 18 to 18/69 -CFT */
else if (stat < 98) total += 2; /* 18/70 to 18/79 -CFT */
else if (stat < 108) total += 3; /* 18/80 to 18/89 -CFT */
else if (stat < 118) total += 4; /* 18/90 to 18/99 -CFT */
else if (stat < 128) total += 5; /* 18/100 to 18/109 -CFT */
else if (stat < 138) total += 6;
else if (stat < 148) total += 7;
else if (stat < 158) total += 8;
else if (stat < 168) total += 9;
else if (stat < 178) total +=10;
else if (stat < 188) total +=11;
else if (stat < 198) total +=12;
else if (stat < 218) total +=13;
else if (stat < 228) total +=14;
else total += 16;
return (total);
}
/* Returns a character's adjustment to armor class -JWT- */
int
toac_adj()
{
register int stat;
stat = py.stats.use_stat[A_DEX];
if (stat < 4) return(-4);
else if (stat == 4) return(-3);
else if (stat == 5) return(-2);
else if (stat == 6) return(-1);
else if (stat < 15) return( 0);
else if (stat < 18) return( 1);
else if (stat < 58) return( 2); /* 18 to 18/49 -CFT */
else if (stat < 98) return( 3); /* 18/50 to 18/79 -CFT */
else if (stat < 108) return( 4); /* 18/80 to 18/89 -CFT */
else if (stat < 118) return( 5); /* 18/90 to /99 -CFT */
else if (stat < 128) return( 6); /* /100 to /109 -CFT */
else if (stat < 138) return( 7);
else if (stat < 148) return( 8);
else if (stat < 158) return( 9);
else if (stat < 168) return(10);
else if (stat < 178) return(11);
else if (stat < 188) return(12);
else if (stat < 198) return(13);
else if (stat < 218) return(14);
else if (stat < 228) return(15);
else return(17);
}
/* Returns a character's adjustment to disarm -RAK- */
int
todis_adj()
{
register int stat;
stat = py.stats.use_stat[A_DEX];
if (stat <= 3) return(-8);
else if (stat == 4) return(-6);
else if (stat == 5) return(-4);
else if (stat == 6) return(-2);
else if (stat == 7) return(-1);
else if (stat < 13) return( 0);
else if (stat < 16) return( 1);
else if (stat < 18) return( 2);
else if (stat < 58) return( 4); /* 18 to 18/49 -CFT */
else if (stat < 88) return( 5); /* 18/50 to 18/69 -CFT */
else if (stat < 108) return( 6); /* 18/70 to 18/89 -CFT */
else if (stat < 118) return( 7); /* 18/90 to 18/99 -CFT */
else return( 8); /* 18/100 and over -CFT */
}
/* Returns a character's adjustment to damage -JWT- */
int
todam_adj()
{
register int stat;
stat = py.stats.use_stat[A_STR];
if (stat < 4) return(-2);
else if (stat < 5) return(-1);
else if (stat < 16) return( 0);
else if (stat < 17) return( 1);
else if (stat < 18) return( 2);
else if (stat < 88) return( 3); /* 18 to 18/69 -CFT */
else if (stat < 98) return( 4); /* 18/70 to 18/79 -CFT */
else if (stat < 108) return( 5); /* 18/80 to 18/89 -CFT */
else if (stat < 118) return( 5); /* 18/90 to 18/99 -CFT */
else if (stat < 128) return( 6); /* 18/100 to /109 -CFT */
else if (stat < 138) return( 7);
else if (stat < 148) return( 8);
else if (stat < 158) return( 9);
else if (stat < 168) return(10);
else if (stat < 178) return(11);
else if (stat < 188) return(12);
else if (stat < 198) return(13);
else if (stat < 218) return(14);
else if (stat < 228) return(16);
else return(20);
}
/* Prints character-screen info -RAK- */
void
prt_stat_block()
{
register int32u status;
register struct misc *m_ptr;
register int i;
m_ptr = &py.misc;
prt_field(race[py.misc.prace].trace, 1, STAT_COLUMN);
prt_field(class[py.misc.pclass].title, 2, STAT_COLUMN);
prt_field(title_string(), 3, STAT_COLUMN);
for (i = 0; i < 6; i++)
prt_stat(i);
prt_num("LEV", (int)m_ptr->lev, 12, STAT_COLUMN);
prt_lnum("EXP", m_ptr->exp, 13, STAT_COLUMN);
prt_num("MNA", m_ptr->cmana, 14, STAT_COLUMN);
prt_num("MHP", m_ptr->mhp, 15, STAT_COLUMN);
prt_num("CHP", m_ptr->chp, 16, STAT_COLUMN);
prt_chp(); /* this will overwrite hp, in color, if
* needed. -CFT */
prt_num("AC ", m_ptr->dis_ac, 18, STAT_COLUMN);
prt_lnum("AU ", m_ptr->au, 19, STAT_COLUMN);
prt_winner();
prt_cut();
prt_stun();
prt_study();
status = py.flags.status;
if ((PY_HUNGRY | PY_WEAK) & status)
prt_hunger();
if (PY_BLIND & status)
prt_blind();
if (PY_CONFUSED & status)
prt_confused();
if (PY_FEAR & status)
prt_afraid();
if (PY_POISONED & status)
prt_poisoned();
if ((PY_SEARCH | PY_REST) & status)
prt_state();
/* if speed non zero, print it, modify speed if Searching */
if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0)
prt_speed();
prt_equippy_chars();
}
/* EQUIPMENT CHARACTER HANDLER - DGK */
void
#ifdef __STDC__
prt_equippy_chars(void)
#else
prt_equippy_chars()
#endif
{
int i, j;
inven_type *i_ptr;
vtype out_val;
out_val[1]='\0';
for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) {
i_ptr = &inventory[i];
j = i - INVEN_WIELD;
if (!equippy_chars || (i_ptr->tval == TV_NOTHING))
out_val[0] = ' ';
else
out_val[0] = (int)(i_ptr->tchar);
put_buffer(out_val, 4, j);
}
}
/* Draws entire screen -RAK- */
void
draw_cave()
{
clear_screen();
prt_stat_block();
prt_map();
prt_depth();
}
/* Prints the following information on the screen. -JWT- */
void
put_character()
{
register struct misc *m_ptr;
m_ptr = &py.misc;
clear_screen();
put_buffer("Name :", 2, 1);
put_buffer("Race :", 3, 1);
put_buffer("Sex :", 4, 1);
put_buffer("Class :", 5, 1);
if (character_generated) {
put_buffer(m_ptr->name, 2, 15);
put_buffer(race[m_ptr->prace].trace, 3, 15);
put_buffer((m_ptr->male ? "Male" : "Female"), 4, 15);
put_buffer(class[m_ptr->pclass].title, 5, 15);
}
}
/* Prints the following information on the screen. -JWT- */
void
put_stats()
{
register struct misc *m_ptr;
register int i, temp;
vtype buf;
m_ptr = &py.misc;
for (i = 0; i < 6; i++) {
cnv_stat(py.stats.use_stat[i], buf);
put_buffer(stat_names[i], 2 + i, 61);
put_buffer(buf, 2 + i, 66);
if (py.stats.max_stat[i] > py.stats.cur_stat[i]) {
/* this looks silly, but it happens because modify_stat() only
* looks at cur_stat -CFT */
temp = py.stats.cur_stat[i];
py.stats.cur_stat[i] = py.stats.max_stat[i];
cnv_stat (modify_stat(i,py.stats.mod_stat[i]), buf);
py.stats.cur_stat[i] = temp; /* DON'T FORGET! -CFT */
put_buffer(buf, 2 + i, 73);
}
}
prt_num("+ To Hit ", m_ptr->dis_th, 9, 1);
prt_num("+ To Damage ", m_ptr->dis_td, 10, 1);
prt_num("+ To AC ", m_ptr->dis_tac, 11, 1);
prt_num(" Total AC ", m_ptr->dis_ac, 12, 1);
}
/* Returns a rating of x depending on y -JWT- */
const char *
likert(x, y)
int x, y;
{
if ((x/y) < 0)
return ("Very Bad");
switch ((x / y)) {
case 0:
case 1:
return ("Bad");
case 2:
return ("Poor");
case 3:
case 4:
return ("Fair");
case 5:
return ("Good");
case 6:
return ("Very Good");
case 7:
case 8:
return ("Excellent");
case 9:
case 10:
case 11:
case 12:
case 13:
return ("Superb");
case 14:
case 15:
case 16:
case 17:
return ("Heroic");
default:
return ("Legendary");
}
}
/* Prints age, height, weight, and SC -JWT- */
void
put_misc1()
{
register struct misc *m_ptr;
m_ptr = &py.misc;
prt_num("Age ", (int)m_ptr->age, 2, 32);
prt_num("Height ", (int)m_ptr->ht, 3, 32);
prt_num("Weight ", (int)m_ptr->wt, 4, 32);
prt_num("Social Class ", (int)m_ptr->sc, 5, 32);
}
/* Prints the following information on the screen. -JWT- */
void
put_misc2()
{
register struct misc *m_ptr;
m_ptr = &py.misc;
prt_num("Level ", (int)m_ptr->lev, 9, 28);
prt_lnum("Experience ", m_ptr->exp, 10, 28);
prt_lnum("Max Exp ", m_ptr->max_exp, 11, 28);
if (m_ptr->lev >= MAX_PLAYER_LEVEL) {
char buf[40]; /* for this to look right, the
* following should be spaced the
* same as in the prt_lnum code...
* -CFT */
sprintf(buf, "%s%9s", "Exp to Adv.", "****");
put_buffer(buf, 12, 28);
} else
prt_lnum("Exp to Adv.", (int32) (player_exp[m_ptr->lev - 1] *
m_ptr->expfact / 100), 12, 28);
prt_lnum("Gold ", m_ptr->au, 13, 28);
prt_num("Max Hit Points ", m_ptr->mhp, 9, 52);
prt_num("Cur Hit Points ", m_ptr->chp, 10, 52);
prt_num("Max Mana ", m_ptr->mana, 11, 52);
prt_num("Cur Mana ", m_ptr->cmana, 12, 52);
}
/* Prints ratings on certain abilities -RAK- */
void
put_misc3()
{
int xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev;
vtype xinfra;
register struct misc *p_ptr;
clear_from(14);
p_ptr = &py.misc;
xbth = p_ptr->bth + p_ptr->ptohit * BTH_PLUS_ADJ
+ (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev);
xbthb = p_ptr->bthb + p_ptr->ptohit * BTH_PLUS_ADJ
+ (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev);
/* this results in a range from 0 to 29 */
xfos = 40 - p_ptr->fos;
if (xfos < 0)
xfos = 0;
xsrh = p_ptr->srh;
/* this results in a range from 0 to 9 */
xstl = p_ptr->stl + 1;
xdis = p_ptr->disarm + 2 * todis_adj() + stat_adj(A_INT)
+ (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
xsave = p_ptr->save + stat_adj(A_WIS)
+ (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3);
xdev = p_ptr->save + stat_adj(A_INT)
+ (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3);
(void)sprintf(xinfra, "%d feet", py.flags.see_infra * 10);
put_buffer("(Miscellaneous Abilities)", 15, 25);
put_buffer("Fighting :", 16, 1);
put_buffer(likert(xbth, 12), 16, 15);
put_buffer("Bows/Throw :", 17, 1);
put_buffer(likert(xbthb, 12), 17, 15);
put_buffer("Saving Throw:", 18, 1);
put_buffer(likert(xsave, 6), 18, 15);
put_buffer("Stealth :", 16, 28);
put_buffer(likert(xstl, 1), 16, 42);
put_buffer("Disarming :", 17, 28);
put_buffer(likert(xdis, 8), 17, 42);
put_buffer("Magic Device:", 18, 28);
put_buffer(likert(xdev, 6), 18, 42);
put_buffer("Perception :", 16, 55);
put_buffer(likert(xfos, 3), 16, 69);
put_buffer("Searching :", 17, 55);
put_buffer(likert(xsrh, 6), 17, 69);
put_buffer("Infra-Vision:", 18, 55);
put_buffer(xinfra, 18, 69);
}
/* Used to display the character on the screen. -RAK- */
void
display_char()
{
put_character();
put_misc1();
put_stats();
put_misc2();
put_misc3();
}
/* Gets a name for the character -JWT- */
void
get_name()
{
char tmp[100];
strcpy(tmp, py.misc.name);
prt("Enter your player's name [press <RETURN> when finished]", 21, 2);
put_buffer(&blank_string[BLANK_LENGTH - 15], 2, 15);
#ifdef MAC
/*
* Force player to give a name, would be nice to get name from chooser (STR
* -16096), but that name might be too long
*/
while (!get_string(py.misc.name, 2, 15, 15) || py.misc.name[0] == 0);
#else
if (!get_string(py.misc.name, 2, 15, 15) || py.misc.name[0] == 0) {
strcpy(py.misc.name, tmp);
put_buffer(tmp, 2, 15);
}
#endif
clear_from(20);
#ifdef MAC
/* Use the new name to set save file default name. */
initsavedefaults();
#endif
}
/* Changes the name of the character -JWT- */
void
change_name()
{
register char c;
register int flag;
#ifndef MAC
vtype temp;
#endif
flag = FALSE;
display_char();
do {
prt("<f>ile character description. <c>hange character name.", 21, 2);
c = inkey();
switch (c) {
case 'c':
get_name();
flag = TRUE;
break;
case 'f':
#ifdef MAC
/* On mac, file_character() gets filename with std file dialog. */
if (file_character())
flag = TRUE;
#else
prt("File name:", 0, 0);
if (get_string(temp, 0, 10, 60) && temp[0])
if (file_character(temp))
flag = TRUE;
#endif
break;
case ESCAPE:
case ' ':
case '\n':
case '\r':
flag = TRUE;
break;
default:
bell();
break;
}
}
while (!flag);
}
/* Destroy an item in the inventory -RAK- */
void
inven_destroy(item_val)
int item_val;
{
register int j;
register inven_type *i_ptr;
i_ptr = &inventory[item_val];
if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX)) {
i_ptr->number--;
inven_weight -= i_ptr->weight;
} else {
inven_weight -= i_ptr->weight * i_ptr->number;
for (j = item_val; j < inven_ctr - 1; j++)
inventory[j] = inventory[j + 1];
invcopy(&inventory[inven_ctr - 1], OBJ_NOTHING);
inven_ctr--;
}
py.flags.status |= PY_STR_WGT;
}
/*
* Copies the object in the second argument over the first argument. However,
* the second always gets a number of one except for ammo etc.
*/
void
take_one_item(s_ptr, i_ptr)
register inven_type *s_ptr, *i_ptr;
{
*s_ptr = *i_ptr;
if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN)
&& (s_ptr->subval <= ITEM_SINGLE_STACK_MAX))
s_ptr->number = 1;
}
/* Drops an item from inventory to given location -RAK- */
void
inven_drop(item_val, drop_all)
register int item_val, drop_all;
{
int i;
register inven_type *i_ptr;
vtype prt2;
bigvtype prt1;
i_ptr = &inventory[item_val];
if (cave[char_row][char_col].tptr != 0)
(void)delete_object(char_row, char_col);
i = popt();
t_list[i] = *i_ptr;
cave[char_row][char_col].tptr = i;
if (item_val >= INVEN_WIELD)
takeoff(item_val, -1);
else {
if (drop_all || i_ptr->number == 1) {
inven_weight -= i_ptr->weight * i_ptr->number;
inven_ctr--;
while (item_val < inven_ctr) {
inventory[item_val] = inventory[item_val + 1];
item_val++;
}
invcopy(&inventory[inven_ctr], OBJ_NOTHING);
} else {
t_list[i].number = 1;
inven_weight -= i_ptr->weight;
i_ptr->number--;
}
objdes(prt1, &t_list[i], TRUE);
(void)sprintf(prt2, "Dropped %s.", prt1);
msg_print(prt2);
}
py.flags.status |= PY_STR_WGT;
}
/* Destroys a type of item on a given percent chance -RAK- */
int
inven_damage(typ, perc)
#ifdef MSDOS
int (*typ) (inven_type *);
#else
int (*typ) ();
#endif
register int perc;
{
register int index, i, j, offset;
vtype tmp_str, out_val;
j = 0;
offset = randint(inven_ctr);
for (index = 0; index < inven_ctr; index++) {
i = (index + offset) % inven_ctr; /* be clever and not destroy the first item */
if ((*typ) (&inventory[i]) && (randint(100) < perc)) {
objdes(tmp_str, &inventory[i], FALSE);
sprintf(out_val, "%sour %s (%c) %s destroyed!",
((inventory[i].subval <= ITEM_SINGLE_STACK_MAX) &&
(inventory[i].number > 1)) /* stacked single items */
? "One of y" : "Y",
tmp_str, i + 'a',
((inventory[i].subval > ITEM_SINGLE_STACK_MAX) &&
(inventory[i].number > 1)) /* stacked group items */
? "were" : "was");
msg_print(out_val);
inven_destroy(i);
j++;
}
}
return (j);
}
/* Computes current weight limit -RAK- */
int
weight_limit()
{
register int32 weight_cap;
weight_cap = (long)py.stats.use_stat[A_STR] * (long)PLAYER_WEIGHT_CAP
+ (long)py.misc.wt;
if (weight_cap > 3000L)
weight_cap = 3000L;
return ((int)weight_cap);
}
/* this code must be identical to the inven_carry() code below */
int
inven_check_num(t_ptr)
register inven_type *t_ptr;
{
register int i;
if (inven_ctr < INVEN_WIELD)
return TRUE;
else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
for (i = 0; i < inven_ctr; i++)
if (inventory[i].tval == t_ptr->tval &&
inventory[i].subval == t_ptr->subval &&
/* make sure the number field doesn't overflow */
((int)inventory[i].number + (int)t_ptr->number < 256) &&
/* they always stack (subval < 192), or else they have same p1 */
((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
/* only stack if both or neither are identified */
&& (known1_p(&inventory[i]) == known1_p(t_ptr)))
return TRUE;
return FALSE;
}
/* return FALSE if picking up an object would change the players speed */
int
inven_check_weight(i_ptr)
register inven_type *i_ptr;
{
register int i, new_inven_weight;
i = weight_limit();
new_inven_weight = i_ptr->number * i_ptr->weight + inven_weight;
if (i < new_inven_weight)
i = new_inven_weight / (i + 1);
else
i = 0;
if (pack_heavy != i)
return FALSE;
else
return TRUE;
}
/* Are we strong enough for the current pack and weapon? -CJS- */
void
check_strength()
{
register int i;
register inven_type *i_ptr;
static int notlike = FALSE;
i_ptr = &inventory[INVEN_WIELD];
if (i_ptr->tval != TV_NOTHING
&& (py.stats.use_stat[A_STR] * 15 < i_ptr->weight)) {
if (weapon_heavy == FALSE) {
msg_print("You have trouble wielding such a heavy weapon.");
weapon_heavy = TRUE;
calc_bonuses();
}
} else if (weapon_heavy == TRUE) {
weapon_heavy = FALSE;
if (i_ptr->tval != TV_NOTHING)
msg_print("You are strong enough to wield your weapon.");
else
msg_print("You feel relieved to put down your heavy weapon.");
calc_bonuses();
}
i = weight_limit();
if (i < inven_weight)
i = inven_weight / (i + 1);
else
i = 0;
if (pack_heavy != i) {
if (pack_heavy < i)
msg_print("Your pack is so heavy that it slows you down.");
else
msg_print("You move more easily under the weight of your pack.");
change_speed(i - pack_heavy);
pack_heavy = i;
}
py.flags.status &= ~PY_STR_WGT;
if (py.misc.pclass == 2 && !notlike) {
if ((i_ptr->tval == TV_SWORD || i_ptr->tval == TV_POLEARM)
&& ((i_ptr->flags2 & TR_BLESS_BLADE) == 0)) {
notlike = TRUE;
msg_print("You do not feel comfortable with your weapon.");
}
} else if (py.misc.pclass == 2 && notlike) {
if (i_ptr->tval == TV_NOTHING) {
notlike = FALSE;
msg_print("You feel comfortable again after removing that weapon.");
} else if (!(i_ptr->tval == TV_SWORD || i_ptr->tval == TV_POLEARM)
|| !((i_ptr->flags2 & TR_BLESS_BLADE) == 0)) {
notlike = FALSE;
msg_print("You feel comfortable with your weapon once more.");
}
}
}
/*
* Add an item to players inventory. Return the item position for a
* description if needed. -RAK- this code must be identical to
* the inven_check_num() code above
*/
/*
* Okay, here's my inven_carry() function (from misc2.c, I think). Just
* replace the existing inven_carry() with this one, and items will sort into
* place, with mage spellbooks coming first for mages, rangers, and rogues.
* Also, this will make Tenser's book sort after all the mage books except
* Raals, instead of in the middle of them (which always seemed strange to
* me). -CFT
*/
int
inven_carry(i_ptr)
register inven_type *i_ptr;
{
register int locn = 0, i;
register int typ, subt;
register inven_type *t_ptr;
int known1p, always_known1p;
int tval_tmp; /* used to make magic books before pray
* books if magicuser */
int stacked = FALSE;
typ = i_ptr->tval;
subt = i_ptr->subval;
known1p = known1_p(i_ptr);
always_known1p = (object_offset(i_ptr) == -1);
if (inven_ctr >= INVEN_WIELD) /* sanity checking to prevent the inv from */
inven_ctr = INVEN_WIELD; /* running over the equipment list -CWS */
/*
* to prevent nasty losses of objects, we first look through entire inven for
* a place to stack, w/o assuming the inventory is sorted. -CFT
*/
if (subt >= ITEM_SINGLE_STACK_MIN) {
for (locn = 0; locn < inven_ctr; locn++) {
t_ptr = &inventory[locn];
if (t_ptr->tval == typ &&
t_ptr->subval == subt &&
/* make sure the number field doesn't overflow */
((int)t_ptr->number + (int)i_ptr->number < 256) &&
/* they always stack (subval < 192), or else they have same p1 */
((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1))
/* only stack if both or neither are identified */
&& (known1_p(&inventory[locn]) == known1p)) {
stacked = TRUE; /* note that we did process the item -CFT */
t_ptr->number += i_ptr->number;
/* if player bought at bargin price, then make sure he can't sell back
* for normal value. This is unfair, since it robs the value from items,
* but it does prevent the player from "milking" the stores for cash.
*/
if (i_ptr->cost < t_ptr->cost)
t_ptr->cost = i_ptr->cost;
break;
} /* if it stacks here */
} /* for loop */
} /* if it stacks, try to stack it... */
if (!stacked) {
/* either it doesn't stack anyway, or it didn't match anything in the inventory.
* Now try to insert. -CFT */
for (locn = 0;; locn++) {
t_ptr = &inventory[locn];
/* For items which are always known1p, i.e. never have a 'color',
* insert them into the inventory in sorted order.
*/
if ((typ == TV_PRAYER_BOOK) && (class[py.misc.pclass].spell == MAGE))
typ = TV_MAGIC_BOOK - 1;
/* sort is in descending, so this will be immediately after magic books.
* It helps that there is no tval that uses this. -CFT
*/
tval_tmp = t_ptr->tval;
if ((tval_tmp == TV_PRAYER_BOOK) &&
(class[py.misc.pclass].spell == MAGE))
tval_tmp = TV_MAGIC_BOOK - 1;
/* sort is in descending, so this will be immediately after magic books.
* It helps that there is no tval that uses this. -CFT
*/
if ((typ > tval_tmp) || /* sort by desc tval */
(always_known1p && /* if always known, then sort by inc level, */
(typ == tval_tmp) && /* then by inc subval */
((i_ptr->level < t_ptr->level) ||
((i_ptr->level == t_ptr->level) && (subt < t_ptr->subval))))) {
for (i = inven_ctr - 1; i >= locn; i--)
inventory[i + 1] = inventory[i];
inventory[locn] = *i_ptr;
inven_ctr++;
break;
}
}
}
inven_weight += i_ptr->number * i_ptr->weight;
py.flags.status |= PY_STR_WGT;
return locn;
}
/* Returns spell chance of failure for spell -RAK- */
int
spell_chance(spell)
int spell;
{
register spell_type *s_ptr;
register int chance;
register int stat;
int minfail;
s_ptr = &magic_spell[py.misc.pclass - 1][spell];
chance = s_ptr->sfail - 3 * (py.misc.lev - s_ptr->slevel);
if (class[py.misc.pclass].spell == MAGE)
stat = A_INT;
else
stat = A_WIS;
chance -= 3 * (stat_adj(stat) - 1);
if (s_ptr->smana > py.misc.cmana)
chance += 5 * (s_ptr->smana - py.misc.cmana);
switch (stat_adj(stat)) {
case 0:
minfail = 50;
break; /* I doubt can cast spells with stat this
* low, anyways... */
case 1:
minfail = 12;
break; /* 8-14 stat */
case 2:
minfail = 8;
break; /* 15-17 stat */
case 3:
minfail = 5;
break; /* 18-18/49 stat */
case 4:
minfail = 4;
break; /* 18/50-18/69 */
case 5:
minfail = 4;
break; /* 18/70-18/89 */
case 6:
minfail = 3;
break; /* 18/90-18/99 */
case 7:
minfail = 3;
break; /* 18/100 */
case 8:
case 9:
case 10:
minfail = 2;
break; /* 18/101 - /130 */
case 11:
case 12:
minfail = 2;
break; /* /131 - /150 */
case 13:
case 14:
minfail = 1;
break; /* /151 - /170 */
case 15:
case 16:
minfail = 1;
break; /* /171 - /200 */
default:
minfail = 0;
break; /* > 18/200 */
}
if ((minfail < 5) && (py.misc.pclass != 1) && (py.misc.pclass != 2))
minfail = 5; /* only mages/priests can get best
* chances... */
if (py.misc.pclass == 2) { /* Big prayer penalty for edged weapons
* -DGK */
register inven_type *i_ptr = &inventory[INVEN_WIELD];
if ((i_ptr->tval == TV_SWORD) || (i_ptr->tval == TV_POLEARM))
if ((i_ptr->flags2 & TR_BLESS_BLADE) == 0)
chance += 25;
}
if (chance > 95)
chance = 95;
else if (chance < minfail)
chance = minfail;
return chance;
}
/* Print list of spells -RAK- */
/*
* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num >=0:
* spells numbered by offset from nonconsec
*/
void
print_spells(spell, num, comment, nonconsec)
int *spell;
register int num;
int comment, nonconsec;
{
register int i, j;
vtype out_val;
register spell_type *s_ptr;
int col, offset;
const char *p;
char spell_char;
if (comment)
col = 22;
else
col = 31;
offset = (class[py.misc.pclass].spell == MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
erase_line(1, col);
put_buffer("Name", 1, col + 5);
put_buffer("Lv Mana Fail", 1, col + 35);
/* only show the first 22 choices */
if (num > 22)
num = 22;
for (i = 0; i < num; i++) {
j = spell[i];
s_ptr = &magic_spell[py.misc.pclass - 1][j];
if (comment == FALSE)
p = "";
else if (j >= 32 ? ((spell_forgotten2 & (1L << (j - 32))) != 0)
: ((spell_forgotten & (1L << j)) != 0))
p = " forgotten";
else if (j >= 32 ? ((spell_learned2 & (1L << (j - 32))) == 0)
: ((spell_learned & (1L << j)) == 0))
p = " unknown";
else if (j >= 32 ? ((spell_worked2 & (1L << (j - 32))) == 0)
: ((spell_worked & (1L << j)) == 0))
p = " untried";
else
p = "";
/* determine whether or not to leave holes in character choices,
* nonconsec -1 when learning spells, consec offset>=0 when asking which
* spell to cast
*/
if (nonconsec == -1)
spell_char = 'a' + i;
else
spell_char = 'a' + j - nonconsec;
(void)sprintf(out_val, " %c) %-30s%2d %4d %3d%%%s", spell_char,
spell_names[j + offset], s_ptr->slevel, s_ptr->smana,
spell_chance(j), p);
prt(out_val, 2 + i, col);
}
}
/* Returns spell pointer -RAK- */
int
get_spell(spell, num, sn, sc, prompt, first_spell)
int *spell;
register int num;
register int *sn, *sc;
const char *prompt;
int first_spell;
{
register spell_type *s_ptr;
int flag, redraw, offset, i;
char choice;
vtype out_str, tmp_str;
*sn = (-1);
flag = FALSE;
(void)sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
spell[0] + 'a' - first_spell, spell[num - 1] + 'a' - first_spell,
prompt);
redraw = FALSE;
offset = (class[py.misc.pclass].spell == MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
while (flag == FALSE && get_com(out_str, &choice)) {
if (isupper((int)choice)) {
*sn = choice - 'A' + first_spell;
/* verify that this is in spell[], at most 22 entries in spell[] */
for (i = 0; i < num; i++)
if (*sn == spell[i])
break;
if (i == num)
*sn = (-2);
else {
s_ptr = &magic_spell[py.misc.pclass - 1][*sn];
(void)sprintf(tmp_str, "Cast %s (%d mana, %d%% fail)?",
spell_names[*sn + offset], s_ptr->smana,
spell_chance(*sn));
if (get_check(tmp_str))
flag = TRUE;
else
*sn = (-1);
}
} else if (islower((int)choice)) {
*sn = choice - 'a' + first_spell;
/* verify that this is in spell[], at most 22 entries in spell[] */
for (i = 0; i < num; i++)
if (*sn == spell[i])
break;
if (i == num)
*sn = (-2);
else
flag = TRUE;
} else if (choice == '*') {
/* only do this drawing once */
if (!redraw) {
save_screen();
redraw = TRUE;
print_spells(spell, num, FALSE, first_spell);
}
} else if (isalpha((int)choice))
*sn = (-2);
else {
*sn = (-1);
bell();
}
if (*sn == -2) {
sprintf(tmp_str, "You don't know that %s.",
(class[py.misc.pclass].spell == MAGE) ? "spell" : "prayer");
msg_print(tmp_str);
}
}
if (redraw)
restore_screen();
erase_line(MSG_LINE, 0);
if (flag)
*sc = spell_chance(*sn);
return (flag);
}
/* calculate number of spells player should have, and learn forget spells
* until that number is met -JEW-
*/
void
calc_spells(stat)
int stat;
{
register int i;
register int32u mask;
int32u spell_flag;
int j, offset;
int num_allowed, new_spells, num_known, levels;
vtype tmp_str;
const char *p;
register struct misc *p_ptr;
register spell_type *msp_ptr;
p_ptr = &py.misc;
msp_ptr = &magic_spell[p_ptr->pclass - 1][0];
if (stat == A_INT) {
p = "spell";
offset = SPELL_OFFSET;
} else {
p = "prayer";
offset = PRAYER_OFFSET;
}
/* check to see if know any spells greater than level, eliminate them */
for (i = 31, mask = 0x80000000L; mask; mask >>= 1, i--) {
if (mask & spell_learned) {
if (msp_ptr[i].slevel > p_ptr->lev) {
spell_learned &= ~mask;
spell_forgotten |= mask;
(void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
spell_names[i + offset]);
msg_print(tmp_str);
}
}
if (mask & spell_learned2) {
if (msp_ptr[i + 32].slevel > p_ptr->lev) {
spell_learned2 &= ~mask;
spell_forgotten2 |= mask;
(void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
spell_names[i + offset + 32]);
msg_print(tmp_str);
}
}
}
/* calc number of spells allowed */
levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
switch (stat_adj(stat)) {
case 0:
num_allowed = 0;
break;
case 1:
case 2:
case 3:
num_allowed = 1 * levels;
break;
case 4:
case 5:
num_allowed = 3 * levels / 2;
break;
case 6:
num_allowed = 2 * levels;
break;
default:
num_allowed = 5 * levels / 2;
break;
}
num_known = 0;
for (mask = 0x1; mask; mask <<= 1) {
if (mask & spell_learned)
num_known++;
if (mask & spell_learned2)
num_known++;
}
new_spells = num_allowed - num_known;
if (new_spells > 0) {
/* remember forgotten spells while forgotten spells exist of new_spells
* positive, remember the spells in the order that they were learned
*/
for (i = 0; ((spell_forgotten | spell_forgotten2) && new_spells
&& (i < num_allowed) && (i < 64)); i++) {
/* j is (i+1)th spell learned */
j = spell_order[i];
/* shifting by amounts greater than number of bits in long gives an
* undefined result, so don't shift for unknown spells
*/
if (j == 99)
continue; /* don't process unknown spells... -CFT */
if (j < 32) { /* use spell_learned, spell_forgotten...
* -CFT */
mask = 1L << j; /* bit in spell fields */
if (mask & spell_forgotten) {
if (msp_ptr[j].slevel <= p_ptr->lev) {
spell_forgotten &= ~mask;
spell_learned |= mask;
new_spells--;
(void)sprintf(tmp_str, "You have remembered the %s of %s.", p,
spell_names[j + offset]);
msg_print(tmp_str);
} else
num_allowed++; /* if was too high lv to remember */
} /* if mask&spell_forgotten */
}
/* j < 32 */
else { /* j > 31, use spell_learned2,
* spell_forgotten2... -CFT */
mask = 1L << (j - 32); /* bit in spell fields */
if (mask & spell_forgotten2) {
if (msp_ptr[j].slevel <= p_ptr->lev) {
spell_forgotten2 &= ~mask;
spell_learned2 |= mask;
new_spells--;
(void)sprintf(tmp_str, "You have remembered the %s of %s.", p,
spell_names[j + offset]);
msg_print(tmp_str);
} else
num_allowed++; /* if was too high lv to remember */
} /* if mask&spell_forgotten2 */
} /* j > 31 */
} /* for loop... */
if (new_spells > 0) {
/* determine which spells player can learn */
/*
* must check all spells here, in gain_spell() we actually check if
* the books are present
*/
/* only bother with spells learnable by class -CFT */
spell_flag = spellmasks[py.misc.pclass][0] & ~spell_learned;
mask = 0x1;
i = 0;
for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
if (spell_flag & mask) {
spell_flag &= ~mask;
if (msp_ptr[j].slevel <= p_ptr->lev)
i++;
}
/* only bother with spells learnable by class -CFT */
spell_flag = spellmasks[py.misc.pclass][1] & ~spell_learned2;
mask = 0x1;
for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
if (spell_flag & mask) {
spell_flag &= ~mask;
if (msp_ptr[j + 32].slevel <= p_ptr->lev)
i++;
}
if (new_spells > i)
new_spells = i;
}
} else if (new_spells < 0) {
/* forget spells until new_spells zero or no more spells know, spells are
* forgotten in the opposite order that they were learned
*/
for (i = 63; new_spells && (spell_learned | spell_learned2); i--) {
/* j is the (i+1)th spell learned */
j = spell_order[i];
/* shifting by amounts greater than number of bits in long gives an
* undefined result, so don't shift for unknown spells
*/
if (j == 99)
continue; /* don't process unknown spells... -CFT */
if (j < 32) { /* use spell_learned, spell_forgotten...
* -CFT */
mask = 1L << j; /* bit in spell fields */
if (mask & spell_learned) {
spell_learned &= ~mask;
spell_forgotten |= mask;
new_spells++;
(void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
spell_names[j + offset]);
msg_print(tmp_str);
} /* if mask&spell_learned */
}
/* j < 32 */
else { /* j > 31, use spell_learned2,
* spell_forgotten2... -CFT */
mask = 1L << (j - 32); /* bit in spell fields */
if (mask & spell_learned2) {
spell_learned2 &= ~mask;
spell_forgotten2 |= mask;
new_spells++;
(void)sprintf(tmp_str, "You have forgotten the %s of %s.", p,
spell_names[j + offset]);
msg_print(tmp_str);
} /* if mask&spell_learned2 */
} /* j > 31 */
} /* for loop... */
new_spells = 0; /* we've forgotten, so we shouldn't be
* learning any... */
}
if (new_spells != py.flags.new_spells) {
if (new_spells > 0 && py.flags.new_spells == 0) {
(void)sprintf(tmp_str, "You can learn some new %ss now.", p);
msg_print(tmp_str);
}
py.flags.new_spells = new_spells;
py.flags.status |= PY_STUDY;
}
}
/* gain spells when player wants to - jw */
void
gain_spells()
{
char query;
int stat, diff_spells, new_spells;
int spells[63], offset, last_known;
register int i, j;
register int32u spell_flag = 0, spell_flag2 = 0, mask;
vtype tmp_str;
struct misc *p_ptr;
register spell_type *msp_ptr;
if (!py.misc.pclass) {
msg_print("A warrior learn magic??? HA!");
return;
}
i = 0;
if (py.flags.blind > 0)
msg_print("You can't see to read your spell book!");
else if (no_light())
msg_print("You have no light to read by.");
else if (py.flags.confused > 0)
msg_print("You are too confused.");
else
i = 1;
if (i == 0)
return;
new_spells = py.flags.new_spells;
diff_spells = 0;
p_ptr = &py.misc;
msp_ptr = &magic_spell[p_ptr->pclass - 1][0];
if (class[p_ptr->pclass].spell == MAGE) {
stat = A_INT;
offset = SPELL_OFFSET;
} else {
stat = A_WIS;
offset = PRAYER_OFFSET;
}
for (last_known = 0; last_known < 64; last_known++)
if (spell_order[last_known] == 99)
break;
if (!new_spells) {
(void)sprintf(tmp_str, "You can't learn any new %ss!",
(stat == A_INT ? "spell" : "prayer"));
msg_print(tmp_str);
free_turn_flag = TRUE;
} else {
/* determine which spells player can learn */
/* mages need the book to learn a spell, priests do not need the book */
spell_flag = 0;
spell_flag2 = 0;
for (i = 0; i < inven_ctr; i++)
if (((stat == A_INT) && (inventory[i].tval == TV_MAGIC_BOOK))
|| ((stat == A_WIS) && (inventory[i].tval == TV_PRAYER_BOOK))) {
spell_flag |= inventory[i].flags;
spell_flag2 |= inventory[i].flags2;
}
}
/* clear bits for spells already learned */
spell_flag &= ~spell_learned;
spell_flag2 &= ~spell_learned2;
mask = 0x1;
i = 0;
for (j = 0, mask = 0x1; (spell_flag | spell_flag2); mask <<= 1, j++) {
if (spell_flag & mask) {
spell_flag &= ~mask;
if (msp_ptr[j].slevel <= p_ptr->lev) {
spells[i] = j;
i++;
}
}
if (spell_flag2 & mask) {
spell_flag2 &= ~mask;
if (msp_ptr[j + 32].slevel <= p_ptr->lev) {
spells[i] = j + 32;
i++;
}
}
}
if (new_spells > i) {
msg_print("You seem to be missing a book.");
diff_spells = new_spells - i;
new_spells = i;
}
if (new_spells == 0);
else if (stat == A_INT) {
/* get to choose which mage spells will be learned */
save_screen();
print_spells(spells, i, FALSE, -1);
while (new_spells && get_com("Learn which spell?", &query)) {
j = query - 'a';
/* test j < 23 in case i is greater than 22, only 22 spells are
* actually shown on the screen, so limit choice to those
*/
if (j >= 0 && j < i && j < 22) {
new_spells--;
if (spells[j] < 32)
spell_learned |= 1L << spells[j];
else
spell_learned2 |= 1L << (spells[j] - 32);
spell_order[last_known++] = spells[j];
for (; j <= i - 1; j++)
spells[j] = spells[j + 1];
i--;
erase_line(j + 1, 31);
print_spells(spells, i, FALSE, -1);
} else
bell();
}
restore_screen();
} else {
/* pick a prayer at random */
while (new_spells) {
j = randint(i) - 1;
if (spells[j] < 32)
spell_learned |= 1L << spells[j];
else
spell_learned2 |= 1L << (spells[j] - 32);
spell_order[last_known++] = spells[j];
(void)sprintf(tmp_str,
"You have learned the prayer of %s.",
spell_names[spells[j] + offset]);
msg_print(tmp_str);
for (; j <= i - 1; j++)
spells[j] = spells[j + 1];
i--;
new_spells--;
}
}
py.flags.new_spells = new_spells + diff_spells;
if (py.flags.new_spells == 0)
py.flags.status |= PY_STUDY;
/* set the mana for first level characters when they learn first spell */
if (py.misc.mana == 0)
calc_mana(stat);
}
/* Gain some mana if you know at least one spell -RAK- */
void
calc_mana(stat)
int stat;
{
register int new_mana, levels;
register struct misc *p_ptr;
register int32 value;
register int i;
register inven_type *i_ptr;
int amrwgt, maxwgt;
p_ptr = &py.misc;
if (spell_learned != 0 || spell_learned2 != 0) {
levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
switch (stat_adj(stat)) {
case 0:
new_mana = 0;
break;
case 1:
case 2:
new_mana = 1 * levels;
break;
case 3:
new_mana = 3 * levels / 2;
break;
case 4:
new_mana = 2 * levels;
break;
case 5:
new_mana = 5 * levels / 2;
break;
case 6:
new_mana = 3 * levels;
break;
case 7:
new_mana = 4 * levels;
break;
case 8:
new_mana = 9 * levels / 2;
break;
case 9:
new_mana = 5 * levels;
break;
case 10:
new_mana = 11 * levels / 2;
break;
case 11:
new_mana = 6 * levels;
break;
case 12:
new_mana = 13 * levels / 2;
break;
case 13:
new_mana = 7 * levels;
break;
case 14:
new_mana = 15 * levels / 2;
break;
default:
new_mana = 8 * levels;
break;
}
/* increment mana by one, so that first level chars have 2 mana */
if (new_mana > 0)
new_mana++;
if ((inventory[INVEN_HANDS].tval != TV_NOTHING) &&
!((inventory[INVEN_HANDS].flags & TR_FREE_ACT) ||
((inventory[INVEN_HANDS].flags & TR_DEX) &&
(inventory[INVEN_HANDS].p1 > 0)))
/* gauntlets of dex (or free action - DGK) can hardly interfere w/ spellcasting!
* But cursed ones can! -CFT */
&&(py.misc.pclass == 1 || py.misc.pclass == 3 || py.misc.pclass == 4)) {
new_mana = (3 * new_mana) / 4;
}
/* Start of **NEW ENCUMBRANCE CALCULATION** -DGK- */
amrwgt = 0;
for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) {
i_ptr = &inventory[i];
switch (i) {
case INVEN_HEAD:
case INVEN_BODY:
case INVEN_ARM:
case INVEN_HANDS:
case INVEN_FEET:
case INVEN_OUTER:
amrwgt += i_ptr->weight;
}
}
switch (py.misc.pclass) {
case 1:
maxwgt = 300;
break;
case 2:
maxwgt = 350;
break;
case 3:
maxwgt = 350;
break;
case 4:
maxwgt = 400;
break;
case 5:
maxwgt = 400;
break;
default:
maxwgt = 0;
}
if (amrwgt > maxwgt)
new_mana -= ((amrwgt - maxwgt) / 10);
/* end of new mana calc */
/* if low int/wis, gloves, and lots of heavy armor, new_mana could be
* negative. This would be very unlikely, except when int/wis was high
* enough to compensate for armor, but was severly drained by an annoying
* monster. Since the following code blindly assumes that new_mana is >=
* 0, we must do the work and return here. -CFT
*/
if (new_mana < 1) {
p_ptr->cmana = p_ptr->cmana_frac = p_ptr->mana = 0;
py.flags.status |= PY_MANA;
return; /* now return before we reach code that
* assumes new_mana is positive.... */
}
/* mana can be zero when creating character */
if (p_ptr->mana != new_mana) {
if (p_ptr->mana != 0) {
/*
* change current mana proportionately to change of max mana,
* divide first to avoid overflow, little loss of accuracy
*/
value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
/ p_ptr->mana * new_mana;
p_ptr->cmana = value >> 16;
p_ptr->cmana_frac = value & 0xFFFF;
} else {
p_ptr->cmana = new_mana;
p_ptr->cmana_frac = 0;
}
p_ptr->mana = new_mana;
/* can't print mana here, may be in store or inventory mode */
py.flags.status |= PY_MANA;
}
} else if (p_ptr->mana != 0) {
p_ptr->mana = 0;
p_ptr->cmana = 0;
/* can't print mana here, may be in store or inventory mode */
py.flags.status |= PY_MANA;
}
}
/* Increases hit points and level -RAK- */
static void
gain_level()
{
vtype out_val;
register struct misc *p_ptr;
register class_type *c_ptr;
p_ptr = &py.misc;
p_ptr->lev++;
(void)sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
msg_print(out_val);
calc_hitpoints();
prt_level();
prt_title();
c_ptr = &class[p_ptr->pclass];
if (c_ptr->spell == MAGE) {
calc_spells(A_INT);
calc_mana(A_INT);
} else if (c_ptr->spell == PRIEST) {
calc_spells(A_WIS);
calc_mana(A_WIS);
}
}
/* Prints experience -RAK- */
void
prt_experience()
{
register struct misc *p_ptr;
char out_val[100];
p_ptr = &py.misc;
if (p_ptr->exp > MAX_EXP)
p_ptr->exp = MAX_EXP;
if (p_ptr->lev < MAX_PLAYER_LEVEL)
{
while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp
&& p_ptr->lev < MAX_PLAYER_LEVEL){
gain_level();
if (p_ptr->exp > p_ptr->max_exp) {
/* level was actually gained, not restored:
* this 300 is arbitrary, but it makes human ages work okay,
* and I chose the other racial age adjs based on this as well -CFT
*/
p_ptr->age += randint((int16u)class[p_ptr->pclass].age_adj *
(int16u)race[p_ptr->prace].m_age)/300;
}
}
}
if (p_ptr->exp > p_ptr->max_exp)
p_ptr->max_exp = p_ptr->exp;
(void) sprintf(out_val, "%8ld", (long)p_ptr->exp);
put_buffer(out_val, 13, STAT_COLUMN+4);
}
/* Calculate the players hit points */
void
calc_hitpoints()
{
register int hitpoints;
register struct misc *p_ptr;
register int32 value;
p_ptr = &py.misc;
hitpoints = player_hp[p_ptr->lev - 1] + (con_adj() * p_ptr->lev);
/* always give at least one point per level + 1 */
if (hitpoints < (p_ptr->lev + 1))
hitpoints = p_ptr->lev + 1;
if (py.flags.status & PY_HERO)
hitpoints += 10;
if (py.flags.status & PY_SHERO)
hitpoints += 30;
/* mhp can equal zero while character is being created */
if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0)) {
/* change current hit points proportionately to change of mhp, divide
* first to avoid overflow, little loss of accuracy
*/
value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
* hitpoints;
p_ptr->chp = value >> 16;
p_ptr->chp_frac = value & 0xFFFF;
p_ptr->mhp = hitpoints;
/* can't print hit points here, may be in store or inventory mode */
py.flags.status |= PY_HP;
}
}
/* Inserts a string into a string */
void
insert_str(object_str, mtc_str, insert)
char *object_str;
const char *mtc_str, *insert;
{
int obj_len;
char *bound, *pc;
register int i, mtc_len;
register char *temp_obj;
const char *temp_mtc;
char out_val[80];
mtc_len = strlen(mtc_str);
obj_len = strlen(object_str);
bound = object_str + obj_len - mtc_len;
for (pc = object_str; pc <= bound; pc++) {
temp_obj = pc;
temp_mtc = mtc_str;
for (i = 0; i < mtc_len; i++)
if (*temp_obj++ != *temp_mtc++)
break;
if (i == mtc_len)
break;
}
if (pc <= bound) {
(void)strncpy(out_val, object_str, (int)(pc - object_str));
out_val[(int)(pc - object_str)] = '\0';
if (insert)
(void)strcat(out_val, insert);
(void)strcat(out_val, (char *)(pc + mtc_len));
(void)strcpy(object_str, out_val);
}
}
void
insert_lnum(object_str, mtc_str, number, show_sign)
char *object_str;
register const char *mtc_str;
int32 number;
int show_sign;
{
int mlen;
vtype str1, str2;
register char *string, *tmp_str;
int flag;
flag = 1;
mlen = strlen(mtc_str);
tmp_str = object_str;
do {
string = (char *) index(tmp_str, mtc_str[0]);
if (string == 0)
flag = 0;
else {
flag = strncmp(string, mtc_str, mlen);
if (flag)
tmp_str = string + 1;
}
}
while (flag);
if (string) {
(void)strncpy(str1, object_str, (int)(string - object_str));
str1[(int)(string - object_str)] = '\0';
(void)strcpy(str2, string + mlen);
if ((number >= 0) && (show_sign))
(void)sprintf(object_str, "%s+%ld%s", str1, (long)number, str2);
else
(void)sprintf(object_str, "%s%ld%s", str1, (long)number, str2);
}
}
/* lets anyone enter wizard mode after a disclaimer... - JEW - */
int
enter_wiz_mode()
{
register int answer;
if (!is_wizard(player_uid))
return FALSE;
if (!noscore) {
msg_print("Wizard mode is for debugging and experimenting.");
answer = get_Yn(
"The game will not be scored if you enter wizard mode. Are you sure?");
}
if (noscore || answer) {
noscore |= 0x2;
wizard = TRUE;
return (TRUE);
}
return (FALSE);
}
/* Weapon weight VS strength and dexterity -RAK- */
int
attack_blows(weight, wtohit)
int weight;
int *wtohit;
{
register int adj_weight;
register int str_index, dex_index, s, d;
s = py.stats.use_stat[A_STR];
d = py.stats.use_stat[A_DEX];
if (s * 15 < weight) {
*wtohit = s * 15 - weight;
return 1;
} else {
*wtohit = 0;
if (d < 10)
dex_index = 0;
else if (d < 19)
dex_index = 1;
else if (d < 68)
dex_index = 2;
else if (d < 108)
dex_index = 3;
else if (d < 118)
dex_index = 4;
else if (d == 118)
dex_index = 5;
else if (d < 128)
dex_index = 6;
else if (d < 138)
dex_index = 7;
else if (d < 148)
dex_index = 8;
else if (d < 158)
dex_index = 9;
else if (d < 168)
dex_index = 10;
else
dex_index = 11;
switch (py.misc.pclass) { /* new class-based weight penalties -CWS */
case 0: /* Warriors */
adj_weight = ((s * 10) / ((weight < 30) ? 30 : weight));
break;
case 1: /* Mages */
adj_weight = ((s * 4) / ((weight < 40) ? 40 : weight));
break;
case 2: /* Priests */
adj_weight = ((s * 7) / ((weight < 35) ? 35 : weight));
break;
case 3: /* Rogues */
adj_weight = ((s * 6) / ((weight < 30) ? 30 : weight));
break;
case 4: /* Rangers */
adj_weight = ((s * 8) / ((weight < 35) ? 35 : weight));
break;
default: /* Paladins */
adj_weight = ((s * 8) / ((weight < 30) ? 30 : weight));
break;
}
if (adj_weight < 2)
str_index = 0;
else if (adj_weight < 3)
str_index = 1;
else if (adj_weight < 4)
str_index = 2;
else if (adj_weight < 6)
str_index = 3;
else if (adj_weight < 8)
str_index = 4;
else if (adj_weight < 10)
str_index = 5;
else if (adj_weight < 13)
str_index = 6;
else if (adj_weight < 15)
str_index = 7;
else if (adj_weight < 18)
str_index = 8;
else if (adj_weight < 20)
str_index = 9;
else
str_index = 10;
s = 0; /* do Weapons of Speed */
for (d = INVEN_WIELD; d < INVEN_AUX; d++)
if (inventory[d].flags2 & TR_ATTACK_SPD)
s += inventory[d].p1;
d = (int)blows_table[str_index][dex_index];
if (py.misc.pclass != 0) /* Non-warrior attack penalty */
if (d > 5)
d = 5;
if (py.misc.pclass == 1)
if (d > 4)
d = 4;
d += s;
return ((d < 1) ? 1 : d);
}
}
/* Special damage due to magical abilities of object -RAK- */
int
tot_dam(i_ptr, tdam, monster)
register inven_type *i_ptr;
register int tdam;
int monster;
{
register creature_type *m_ptr;
register recall_type *r_ptr;
int reduced = FALSE;
/* don't resist more than one thing.... -CWS */
if ((((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
(i_ptr->tval == TV_FLASK))) {
m_ptr = &c_list[monster];
r_ptr = &c_recall[monster];
/* Mjollnir? :-> */
if (!(m_ptr->cdefense & IM_LIGHTNING) && (i_ptr->flags2 & TR_LIGHTNING)) {
tdam *= 5;
}
/* Execute Dragon */
else if ((m_ptr->cdefense & DRAGON) && (i_ptr->flags & TR_SLAY_X_DRAGON)) {
tdam *= 5;
r_ptr->r_cdefense |= DRAGON;
}
/* Slay Dragon */
else if ((m_ptr->cdefense & DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON)) {
tdam *= 3;
r_ptr->r_cdefense |= DRAGON;
}
/* Slay Undead */
else if ((m_ptr->cdefense & UNDEAD) && (i_ptr->flags & TR_SLAY_UNDEAD)) {
tdam *= 3;
r_ptr->r_cdefense |= UNDEAD;
}
/* Slay ORC */
else if ((m_ptr->cdefense & ORC) && (i_ptr->flags2 & TR_SLAY_ORC)) {
tdam *= 3;
r_ptr->r_cdefense |= ORC;
}
/* Slay TROLL */
else if ((m_ptr->cdefense & TROLL) && (i_ptr->flags2 & TR_SLAY_TROLL)) {
tdam *= 3;
r_ptr->r_cdefense |= TROLL;
}
/* Slay GIANT */
else if ((m_ptr->cdefense & GIANT) && (i_ptr->flags2 & TR_SLAY_GIANT)) {
tdam *= 3;
r_ptr->r_cdefense |= GIANT;
}
/* Slay DEMON */
else if ((m_ptr->cdefense & DEMON) && (i_ptr->flags2 & TR_SLAY_DEMON)) {
tdam *= 3;
r_ptr->r_cdefense |= DEMON;
}
/* Frost */
else if ((!(m_ptr->cdefense & IM_FROST))
&& (i_ptr->flags & TR_FROST_BRAND)) {
tdam *= 3;
}
/* Fire */
else if ((!(m_ptr->cdefense & IM_FIRE))
&& (i_ptr->flags & TR_FLAME_TONGUE)) {
tdam *= 3;
}
/* Slay Evil */
else if ((m_ptr->cdefense & EVIL) && (i_ptr->flags & TR_SLAY_EVIL)) {
tdam *= 2;
r_ptr->r_cdefense |= EVIL;
}
/* Slay Animal */
else if ((m_ptr->cdefense & ANIMAL) && (i_ptr->flags & TR_SLAY_ANIMAL)) {
tdam *= 2;
r_ptr->r_cdefense |= ANIMAL;
}
/* let's do the resistances */
if (((m_ptr->cdefense & IM_FROST)) && (i_ptr->flags & TR_FROST_BRAND)) {
r_ptr->r_cdefense |= IM_FROST;
tdam = (tdam * 3) / 4;
reduced = TRUE;
}
if (((m_ptr->cdefense & IM_FIRE)) && (i_ptr->flags & TR_FLAME_TONGUE)) {
r_ptr->r_cdefense |= IM_FIRE;
if (!reduced) {
tdam = (tdam * 3) / 4;
reduced = TRUE;
}
}
if (((m_ptr->cdefense & IM_LIGHTNING)) && (i_ptr->flags2 & TR_LIGHTNING)) {
r_ptr->r_cdefense |= IM_LIGHTNING;
if (!reduced) {
tdam = (tdam * 3) / 4;
reduced = TRUE;
}
}
if ((i_ptr->flags2 & TR_IMPACT) && (tdam > 50))
earthquake();
}
return (tdam);
}
/* Critical hits, Nasty way to die. -RAK- */
int
critical_blow(weight, plus, dam, attack_type)
register int weight, plus, dam;
int attack_type;
{
register int critical;
critical = dam;
/* Weight of weapon, plusses to hit, and character level all */
/* contribute to the chance of a critical */
if (randint(5000) <= (int)(weight + 5 * plus
+ (class_level_adj[py.misc.pclass][attack_type]
* py.misc.lev))) {
weight += randint(650);
if (weight < 400) {
critical = 2 * dam + 5;
msg_print("It was a good hit!");
} else if (weight < 700) {
critical = 2 * dam + 10;
msg_print("It was an excellent hit!");
} else if (weight < 900) {
critical = 3 * dam + 15;
msg_print("It was a superb hit!");
} else if (weight < 1300) {
critical = 3 * dam + 20;
msg_print("It was a *GREAT* hit!");
} else {
critical = ((7 * dam) / 2) + 25;
msg_print("It was a *SUPERB* hit!");
}
}
return (critical);
}
/* Given direction "dir", returns new row, column location -RAK- */
/* targeting code stolen from Morgul -CFT */
/* 'dir=0' moves toward target CDW */
int
mmove(dir, y, x)
int dir;
register int *y, *x;
{
register int new_row = 0, new_col = 0;
int boolflag;
switch (dir) {
#ifdef TARGET
case 0: /* targetting code stolen from Morgul -CFT */
new_row = *y;
new_col = *x;
mmove2(&new_row, &new_col,
char_row, char_col,
target_row, target_col);
break;
#endif /* TARGET */
case 1:
new_row = *y + 1;
new_col = *x - 1;
break;
case 2:
new_row = *y + 1;
new_col = *x;
break;
case 3:
new_row = *y + 1;
new_col = *x + 1;
break;
case 4:
new_row = *y;
new_col = *x - 1;
break;
case 5:
new_row = *y;
new_col = *x;
break;
case 6:
new_row = *y;
new_col = *x + 1;
break;
case 7:
new_row = *y - 1;
new_col = *x - 1;
break;
case 8:
new_row = *y - 1;
new_col = *x;
break;
case 9:
new_row = *y - 1;
new_col = *x + 1;
break;
}
boolflag = FALSE;
if ((new_row >= 0) && (new_row < cur_height)
&& (new_col >= 0) && (new_col < cur_width)) {
*y = new_row;
*x = new_col;
boolflag = TRUE;
}
return (boolflag);
}
/* Saving throws for player character. -RAK- */
int
player_saves()
{
/* MPW C couldn't handle the expression, so split it into two parts */
int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
+ (temp * py.misc.lev / 3)))
return (TRUE);
else
return (FALSE);
}
/* Finds range of item in inventory list -RAK- */
int
find_range(item1, item2, j, k)
int item1, item2;
register int *j, *k;
{
register int i;
register inven_type *i_ptr;
int flag;
i = 0;
*j = (-1);
*k = (-1);
flag = FALSE;
i_ptr = &inventory[0];
while (i < inven_ctr) {
if (!flag) {
if ((i_ptr->tval == item1) || (i_ptr->tval == item2)) {
flag = TRUE;
*j = i;
}
} else {
if ((i_ptr->tval != item1) && (i_ptr->tval != item2)) {
*k = i - 1;
break;
}
}
i++;
i_ptr++;
}
if (flag && (*k == -1))
*k = inven_ctr - 1;
return (flag);
}
/* Teleport the player to a new location -RAK- */
void
teleport(dis)
int dis;
{
register int y, x, count;
do {
count = 0;
do {
count += 1;
y = randint(cur_height) - 1;
x = randint(cur_width) - 1;
while (distance(y, x, char_row, char_col) > dis) {
y += ((char_row - y) / 2);
x += ((char_col - x) / 2);
}
}
while (((cave[y][x].fval >= MIN_CLOSED_SPACE) ||
(cave[y][x].cptr >= 2) ||
(t_list[cave[y][x].tptr].index == OBJ_OPEN_DOOR) ||
(cave[y][x].fval == NT_DARK_FLOOR) ||
(cave[y][x].fval == NT_LIGHT_FLOOR)) && count < 1000);
dis *= 2;
} while (count == 1000);
move_rec(char_row, char_col, y, x);
/* unlight area teleported from */
darken_player(char_row, char_col);
char_row = y;
char_col = x;
check_view();
creatures(FALSE);
teleport_flag = FALSE;
}
/* Add a comment to an object description. -CJS- */
void
scribe_object()
{
int item_val, j;
vtype out_val, tmp_str;
if (inven_ctr > 0 || equip_ctr > 0) {
if (get_item(&item_val, "Which one? ", 0, INVEN_ARRAY_SIZE, 0)) {
objdes(tmp_str, &inventory[item_val], TRUE);
(void)sprintf(out_val, "Inscribing %s.", tmp_str);
msg_print(out_val);
if (inventory[item_val].inscrip[0] != '\0')
(void)sprintf(out_val, "Replace \"%s\" with the inscription: ",
inventory[item_val].inscrip);
else
(void)strcpy(out_val, "Inscription: ");
j = 78 - strlen(tmp_str);
if (j > 12)
j = 12;
prt(out_val, 0, 0);
if (get_string(out_val, 0, strlen(out_val), j))
inscribe(&inventory[item_val], out_val);
}
} else
msg_print("You are not carrying anything to inscribe.");
}
/* Append an additional comment to an object description. -CJS- */
void
add_inscribe(i_ptr, type)
inven_type *i_ptr;
int type;
{
i_ptr->ident |= (int8u) type;
}
/* Replace any existing comment in an object description with a new one. CJS */
void
inscribe(i_ptr, str)
inven_type *i_ptr;
const char *str;
{
(void)strcpy(i_ptr->inscrip, str);
}
/* We need to reset the view of things. -CJS- */
void
check_view()
{
register int i, j;
register cave_type *c_ptr, *d_ptr;
c_ptr = &cave[char_row][char_col];
/* Check for new panel */
if (get_panel(char_row, char_col, FALSE))
prt_map();
/* Move the light source */
move_light(char_row, char_col, char_row, char_col);
/* A room of light should be lit. */
if (c_ptr->fval == LIGHT_FLOOR) {
if ((py.flags.blind < 1) && !c_ptr->pl)
light_room(char_row, char_col);
}
/* In doorway of light-room? */
else if (c_ptr->lr && (py.flags.blind < 1)) {
for (i = (char_row - 1); i <= (char_row + 1); i++)
for (j = (char_col - 1); j <= (char_col + 1); j++) {
d_ptr = &cave[i][j];
if ((d_ptr->fval == LIGHT_FLOOR) && !d_ptr->pl)
light_room(i, j);
}
}
}